<?php

namespace Libraries\OAuth2Client;

use InvalidArgumentException;
use AlipayUserInfoAuthRequest;
use AlipaySystemOauthTokenRequest;
use AlipayUserInfoShareRequest ;
use RuntimeException;
use Models\User;

class AlipayOAuth2Client extends OAuth2Client
{
    protected $codeName = 'auth_code';

    public function redirectToAuthorize($redirect_uri, $scopes = array('auth_base'), $state = null)
    {
        $aop = aopClient();

        $request = new AlipayUserInfoAuthRequest();
        $request->setReturnUrl($this->redirectUri);
        $params = [
            'scopes' => $scopes,
        ];
        if($state) {
            $params['state'] = $state;
        }
        $request->setBizContent(json_encode($params));
        $result = $aop->pageExecute($request); 

        echo $result;
    }

    public function getAccessToken($code)
    {
        $request = new AlipaySystemOauthTokenRequest();

        $request->setGrantType('authorization_code');
        $request->setCode($code);

        $aop = aopClient();
        $response = $aop->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        if (property_exists($response, $responseNode)) {
            return array(
                'access_token' => $response->$responseNode->access_token,
                'expires_in' => $response->$responseNode->expires_in,
                'user_id' => $response->$responseNode->user_id,
                'refresh_token' => $response->$responseNode->refresh_token,
                'refresh_token_expires_in' => $response->$responseNode->re_expires_in,
            );
        } else {
            throw new RuntimeException($response->error_response->msg.':'.$response->error_response->sub_msg, $response->error_response->code);
        }
    }

    public function refreshToken($refresh_token)
    {
        $request = AlipaySystemOauthTokenRequest();
        $request->setGrantType('refresh_token');
        $request->setRefreshToken($refresh_token);

        $aop = aopClient();
        $response = $aop->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        if (property_exists($response, $responseNode)) {
            return array(
                'access_token' => $response->$responseNode->access_token,
                'expires_in' => $response->$responseNode->expires_in,
                'user_id' => $response->$responseNode->user_id,
                'refresh_token' => $response->$responseNode->refresh_token,
                'refresh_token_expires_in' => $response->$responseNode->re_expires_in,
            );
        } else {
            throw new RuntimeException($response->error_response->msg.':'.$response->error_response->sub_msg, $response->error_response->code);
        }
    }

    public function getUserInfo($access_token)
    {
        $request = new AlipayUserInfoShareRequest();
        $aop = aopClient();
        $response = $aop->execute($request, $access_token);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $resultCode = $response->$responseNode->code;
        if(!empty($resultCode) && $resultCode == 10000){
            return $response->$responseNode;
        }
        return $response;
    }

    public function saveUser(User $user, $userInfo)
    {
        if (!$user->where('alipay_openid', $userInfo->user_id)->get_one()) {
            $user['alipay_openid'] = $userInfo->user_id;
            $user['username'] = $userInfo->nick_name;
            $user['avatar'] = $userInfo->avatar;
            $user['add_time'] = time();
            if (!$user->add()) {
                $error = get_instance()->db->error();
                throw new RunTimeException("save user failed".$error['message'], $error['code']);
            }
        }

        return $user;
    }

    public function getCode()
    {
        return $_GET[$this->codeName];
    }
}